/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bluetoothserver;


import bluetoothserver.dataStore.Answer;
import bluetoothserver.dataStore.AnswerCollection;
import bluetoothserver.dataStore.Comment;
import bluetoothserver.dataStore.CommentCollection;
import bluetoothserver.dataStore.Question;
import bluetoothserver.dataStore.QuestionCollection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.bluetooth.*;
import java.util.*;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import javax.swing.JOptionPane;

/**
 *
 * @author Philip
 */
public class BluetoothInterface extends Thread{
    private final int JOIN = 1;
    private final int ANSWER = 2;
    private final int COMMENT = 3;
    private final int LEAVE = 4;
    private ArrayList<String> mobileDevices;
    private AnswerCollection answers;
    private CommentCollection comments;
    private String nextQuestion;
    private String[] rearranged;
    

    
    public BluetoothInterface(){
        mobileDevices = new ArrayList<String>();
        answers = AnswerCollection.getInstance();
        comments = CommentCollection.getInstance();
    }
    
    /**
     * Broadcasts the server id so that mobile devices can register
     * @param serverID the id of the server
     * @return a boolean whether it was successful
     */
    public boolean broadcastServerID(String serverID){
        
        return false;
    }
    
    /**
     * Registers a mobile device on the question broadcast system
     * @param rd Remote device being added to the system
     */
    public void registerMobileDevice(String s){
        mobileDevices.add(s);
    }
    
    /**
     * Removes a mobile device from the question broadcast system
     * @param rd Remote device being removed
     */
    public void unsubcribeMobileDevice(String s){
        if(mobileDevices.contains(s)){
            mobileDevices.remove(s);
        }
    }
    
    /**
     * Adds a mobile device to the queue that is transmitting
     * @param o mobile device
     */
    public void SendQuestion(Question q){
        nextQuestion = this.compileMessage(q);
    }
    private void questionSort(String ty,String ti,String an){
        int type = Integer.parseInt(ty);
        if(type == QuestionCollection.MULTIMARK){
            String[] ans = an.split(",");
            for(int i = 0; i < ans.length;i++){
                Answer a = new Answer(ti,type,ans[i]);
                answers.addAnswer(a);
            }
        }else{
        Answer a = new Answer(ti,type,an);
        answers.addAnswer(a);
        }
    }

    private void commentSort(String usr,String com){
        Comment c = new Comment(usr,com);
        comments.addComment(c);
    }

    private String compileMessage(Question q){
        StringBuffer buf = new StringBuffer("");
        buf.append(q.getType()+"\n");
        buf.append(q.getQuestion()+"\n");
        String[] ans = q.getAnswers();

        if(q.getType()== 4){
            //This will randomize the answers
            Random r = new Random();
            String[] ran = new String[ans.length];
            ArrayList<String> a = new ArrayList<String>();
            while(a.size() < ans.length){
                int j = r.nextInt(ans.length);
                if(!a.contains(j+"")){
                    a.add(j+"");
                }
            }
            int j = 0;
            while(j < a.size()){
                int pos =Integer.parseInt(a.get(j));
                ran[pos] = ans[j];
                j++;
            }
            ans = ran;
        }
        rearranged = new String[ans.length];
        for(int i = 0;i < ans.length;i++){
            buf.append(ans[i]+"\n");
            
            rearranged[i] = ans[i];
        }
        String s = new String(buf);
        return s;
    }
    
    private boolean sortData(String received){
        boolean state = false;
        //Splits the string into it's individual parts
        String[] breakdown = received.split("\n");

        //Identifies the type of message
        int i = 0;
        try{
        i = Integer.parseInt(breakdown[0]);
        }catch(Exception ex){
            //display.outputToScreen(ex.getMessage());
        }
        switch(i){
            case JOIN:
                //Method called when a client wants to join the server
                this.registerMobileDevice(breakdown[1]);
                state = true;
                break;
            case ANSWER:
                //Method called when a client is returning an answer to a question
                this.questionSort(breakdown[1], breakdown[2], breakdown[3]);
                state = true;
                break;
            case COMMENT:
                //Method called when a client wants to leave a comment
                this.commentSort(breakdown[1], breakdown[2]);
                break;
            case LEAVE:
                //Method called when a client wants to leave the server
                this.unsubcribeMobileDevice(breakdown[1]);
                break;

        }
        return state;


    }

    @Override
    public void run() {
        
        String serverUUID = "btspp://localhost:"+new UUID("F0E0D0C0B0A000908070605040302010",false).toString()+";name=blueQ"+";authorize=false";
        try {

            LocalDevice.getLocalDevice().setDiscoverable(DiscoveryAgent.GIAC);
        } catch (BluetoothStateException ex) {
            JOptionPane.showMessageDialog(null, "Bluetooth Device could not be found.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        try {
            StreamConnectionNotifier service = (StreamConnectionNotifier) Connector.open(serverUUID);
            //display.outputToScreen("Service Initialized successfully !");

            //This while loop is what deals with incoming communications from the mobile devices
            while(true){
                StreamConnection con = (StreamConnection) service.acceptAndOpen();
                InputStream is = con.openInputStream();
                OutputStream os = con.openOutputStream();
                byte buffer[] = new byte[1024];
                int bytes_read = is.read(buffer);
                String received = new String(buffer,0,bytes_read);
                //display.outputToScreen("Received: "+received);
                
                if(this.sortData(received)){
                    //send the next question to the client
                    os.write(nextQuestion.getBytes());
                    os.flush();
                }
                is.close();
                os.close();
                con.close();
            }

        } catch (IOException ex) {
            //display.outputToScreen(1+ex.getMessage());
        }
        
    }

    public String[] getRearranged(){
        return rearranged;
    }
}